<?php

namespace app\admin\controller;

use app\admin\validate\SysUser as SysUserValidate;
use app\common\business\SysRole as SysRoleBus;
use app\common\business\SysUser as SysUserBus;
use app\common\business\SysDept as SysDeptBus;
use app\common\model\mysql\SysDept as SysDeptModel;
use app\common\business\SysPost as SysPostBus;
use app\common\lib\toCamelCase;
use app\common\model\mysql\SysUserPost;
use app\common\model\mysql\SysUserRole;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use think\facade\Db;

class SysUser extends AuthBase
{
    //获取用户列表查询条件
    public function userListSearch(){
        $where = [];
        // 获取分页参数
        $page = $this->request->get('pageNum', 1);
        $limit = $this->request->get('pageSize', 10);
        $userName = $this->request->get('userName',"");
        $phonenumber = $this->request->get('phonenumber',"");
        $status = $this->request->get("status","");
        $deptId = $this->request->get("deptId","");
        $params = $this->request->get('params',"");
        if($userName){
            $where[] = ['user_name', 'like', '%'.$userName.'%'];
        }
        if($phonenumber){
            $where[] = ['phonenumber', 'like', '%'.$phonenumber.'%'];
        }
        if($deptId){
            $deptId = (new SysDeptModel())->getAllChildrenIds($deptId);
            $where[] = ["dept_id", "in", $deptId];
        }
        if ($status !== null && $status !== '') {
            // 如果$status不为null且不为空字符串，则添加条件到$where数组
            $where[] = ["status", "=", $status];
        }
        $where[] = ["del_flag","=",'0'];
        if($params){
            $where[] = ['create_time',">=",$params['beginTime']." 00:00:00"];
            $where[] = ['create_time',"<=",$params['endTime']." 23:59:59"];
        }
        $where = (new \app\common\business\DataAuth())->index($this->userId,$this->username,$this->dept_id,$where);
        $data = [
            'page'=>$page,
            'limit'=>$limit,
            'where'=>$where['where']
        ];
        return $data;
    }

    //用户列表
    public function userList(){
        try {
            $searchData = $this->userListSearch();
            $userData = (new SysUserBus())->getNormalUser($searchData['where'],'*',$searchData['limit'],$searchData['page']);
            $deptBus = new SysDeptBus();
            foreach ($userData['data'] as &$user) {
                $deptData = $deptBus->getFindNormalDept(['dept_id' => $user['dept_id']]);
                $user['dept'] = $deptData;
            }
            $userData = (new toCamelCase())->toCamelCaseArray($userData);
        }catch (\Exception $e){
            $userData = [];
        }
        return show(config("status.success"),"用户列表",$userData);
    }

    //用户添加
    public function userAdd(){
        if (!$this->request->isPost()) {
            return show(config("status.error"), "请求方式错误");
        }
        // 参数校验
        $params = $this->request->post();
        $data = [
            'dept_id'       => $params['deptId'] ?? 0,
            'email'         => $params['email'] ?? '',
            'nick_name'     => $params['nickName'] ?? '',
            'password'      => $params['password'] ? md5(config("redis.password_salt").$params['password']) : '',
            'phonenumber'   => $params['phonenumber'] ?? '',
            'remark'        => $params['remark'] ?? null,
            'status'        => $params['status'] ?? 0,
            'user_name'     => $params['userName'] ?? '',
        ];
        $validate = new SysUserValidate();
        if (!$validate->check($data)) {
            return show(config("status.error"), $validate->getError());
        }
        try {
            Db::startTrans(); // 开始事务
            $result = (new SysUserBus())->addUser($data);
            if (!$result) {
                return show(config("status.error"), "添加角色失败");
            }
            // 添加用户与岗位关联表
            (new SysUserPost())->insertAllPostUser($result,$params['postIds'] ?? []);
            // 添加用户与角色关联表
            (new SysUserRole())->insertAllUserRole($result,$params['roleIds'] ?? []);
            // 提交事务
            Db::commit();
            return show(config("status.success"), "新增成功", $result);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
    }

    //用户修改
    public function userEdit(){
        $params = request()->param();
        // 验证 userId 是否存在
        if (empty($params['userId'])) {
            return show(config("status.error"), "用户ID不能为空");
        }
        $data = [
            'dept_id'       => $params['deptId'] ?? 0,
            'email'         => $params['email'] ?? '',
            'nick_name'     => $params['nickName'] ?? '',
            //'password'      => $params['password'] ? md5(config("redis.password_salt").$params['password']) : '',
            'phonenumber'   => $params['phonenumber'] ?? '',
            'remark'        => $params['remark'] ?? null,
            'status'        => $params['status'] ?? 0,
            'user_name'     => $params['userName'] ?? '',
        ];
        try {
            Db::startTrans(); // 开始事务
            // 更新用户信息
            $userId = $params['userId'];
            $updateResult = (new SysUserBus())->updateById($userId, $data);
            if (!$updateResult) {
                return show(config("status.error"), "修改用户失败");
            }
            // 删除旧的用户与岗位关联表
            (new SysUserPost())->deleteAllUserPost($userId);
            //删除旧的用户与角色关联表
            (new SysUserRole())->deleteAllUserRole($userId);
            // 添加用户与岗位关联表
            (new SysUserPost())->insertAllPostUser($userId,$params['postIds'] ?? []);
            // 添加用户与角色关联表
            (new SysUserRole())->insertAllUserRole($userId,$params['roleIds'] ?? []);
            // 提交事务
            Db::commit();
            return show(config("status.success"), "修改成功", $userId);
        }catch (\Exception $e){
            // 回滚事务
            Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
    }

    //删除用户
    public function userDel(){
        $user = $this->request->param("user","","trim");
        if(empty($user)){
            return show(config("status.error"),"参数不能为空");
        }
        try {
            Db::startTrans(); // 开始事务
            $result = (new SysUserBus())->DelUserIds($user);
            // 删除旧的用户与岗位关联表
            (new SysUserPost())->deleteAllInUserPost($user);
            //删除旧的用户与角色关联表
            (new SysUserRole())->deleteAllInUserRole($user);
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"删除成功",$result);
    }

    //获取角色与岗位信息
    public function postsAndRolesList(){
        try {
            $userId = $this->request->param("userId", "", "trim");
            $userData = [];
            if ($userId) {
                $userService = new SysUserBus();
                $postService = new SysUserPost();
                $roleService = new SysUserRole();
                $userData = [
                    'postIds' => $postService->getPostIds($userId),
                    'roleIds' => $roleService->getRoleIds($userId),
                    'data' => $userService->getUserById($userId),
                ];
            }

            $postData = (new SysPostBus())->getNormalPostNotPage();
            $whereConditions = [
                ["del_flag","=",0],
                ["role_key","<>","admin"],
            ];
            $roleData = (new SysRoleBus())->getNormalRoleNotPage($whereConditions);
            $data = [
                'posts' => $postData,
                'roles' => $roleData,
            ];
            if ($userId) {
                $data = array_merge($data, $userData);
            }
            $data = (new toCamelCase())->toCamelCaseArray($data);
        }catch (\Exception $e){
            $data = [];
        }
        return show(config("status.success"),"获取角色与岗位信息",$data);
    }

    //更改用户状态
    public function changeStatus(){
        $userId = $this->request->param("userId","","trim");
        $status = $this->request->param("status","","trim");
        // 验证 userId 是否存在
        if (empty($userId)) {
            return show(config("status.error"), "用户ID不能为空");
        }
        if ($status == "") {
            return show(config("status.error"), "用户状态不能为空");
        }
        try {
            $result = (new SysUserBus())->changeStatusUser($userId,$status);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"操作成功",$result);
    }

    //用户重置密码
    public function resetPwd(){
        $userId = $this->request->param("userId","","trim");
        $password = $this->request->param("password","","trim");
        // 验证 userId 是否存在
        if (empty($userId)) {
            return show(config("status.error"), "用户ID不能为空");
        }
        if (empty($password)) {
            return show(config("status.error"), "密码不能为空");
        }
        try {
            $result = (new SysUserBus())->resetPwdUser($userId,$password);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"操作成功",$result);
    }

    //用户导入下载模版
    public function importTemplate(){
        $template = new Template();
        return $template->downloadTemplate('user');
    }

    //用户导入
    public function importData()
    {
        // 检查是否有文件上传
        $file = \think\facade\Request::file('file');
        if (!$file) {
            return show(config("status.error"), "请上传Excel文件");
        }

        // 保存到服务器指定目录
        $saveName = \think\facade\Filesystem::disk('public')->putFile('uploads', $file);
        $filePath = \think\facade\Filesystem::disk('public')->path($saveName);

        // 读取Excel文件
        $spreadsheet = IOFactory::load($filePath);
        $sheet = $spreadsheet->getActiveSheet();

        $data = [];
        $errors = [];

        // 遍历Excel表格，获取数据
        $highestRow = $sheet->getHighestRow();
        for ($row = 2; $row <= $highestRow; $row++) {
            $user_name = $sheet->getCellByColumnAndRow(3, $row)->getValue();
            $email = $sheet->getCellByColumnAndRow(5, $row)->getValue();
            $sex = $sheet->getCellByColumnAndRow(7, $row)->getValue();
            $status = $sheet->getCellByColumnAndRow(8, $row)->getValue();
            // 检查用户名是否已存在和验证邮箱格式
            if ((new SysUserBus())->getUserByName($user_name) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
                if ((new SysUserBus())->getUserByName($user_name)) {
                    $errors[] = "账号 {$user_name} 已存在";
                }
                if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                    $errors[] = "账号 {$user_name} 导入失败：邮箱格式不正确";
                }
                continue; // 当任一条件为真时（即任一检查失败），跳过当前循环
            }
            // 转换性别和状态
            $sex = ($sex == "1" || strtolower($sex) == "女") ? 1 : 0;
            $status = ($status == "1" || strtolower($status) == "停用") ? 1 : 0;
            // 提取其他数据
            $dept_id = $sheet->getCellByColumnAndRow(2, $row)->getValue();
            $nick_name = $sheet->getCellByColumnAndRow(4, $row)->getValue();
            $phonenumber = $sheet->getCellByColumnAndRow(6, $row)->getValue();
            // 构造数据项
            $item = [
                'dept_id' => $dept_id,
                'user_name' => $user_name,
                'nick_name' => $nick_name,
                'email' => $email,
                'phonenumber' => $phonenumber,
                'sex' => $sex,
                'status' => $status,
                'password' => md5(config("redis.password_salt") . config("redis.default_login_password")),
            ];
            $data[] = $item;
        }
        // 处理错误
        if (!empty($errors)) {
            return show(config("status.error"), "很抱歉，导入失败！错误如下：<br/>" . implode("<br/>", $errors));
        }
        try {
            // 批量保存到数据库
            (new SysUserBus())->insertAllUser($data);
            return show(config("status.success"), "恭喜您，数据已全部导入成功！", $data);
        } catch (\Exception $e) {
            return show(config('status.error'),$e->getMessage());
        }
    }

    //用户导出
    public function userExport(){
        $searchData = $this->userListSearch();
        $userData = (new SysUserBus())->getNormalUser($searchData['where'],'*',$searchData['limit'],$searchData['page']);
        // 创建Spreadsheet对象
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        $sheet->mergeCells('A1:K1');
        $sheet->setCellValue('A1', '用户数据');
        // 设置表头
        $header = ['用户序号', '登录名称', '用户名称', '用户邮箱', '手机号码','用户性别','账号状态','最后登录IP','最后登录时间','部门名称','部门负责人'];
        $row = 2;
        $col = 1; // 列索引，从A列开始
        foreach ($header as $column) {
            // 使用setCellValueByColumnAndRow时，第二个参数是列号（整数），第三个参数是值
            $sheet->setCellValueByColumnAndRow($col, $row, $column);
            $col++; // 移动到下一列
        }
        // 使用循环设置列宽
        $columns = ['A', 'B', 'C', 'D', 'E', 'F','G','H','I','J','K']; // 定义需要设置宽度的列
        foreach ($columns as $column) {
            $sheet->getColumnDimension($column)->setWidth(18);
        }
        // 填充数据
        $row = 3;
        $deptBus = (new SysDeptBus());
        foreach ($userData['data'] as $post) {
            $post['status'] = $post['status'] === '0' ? "正常" : "停用";
            $genderMap = [
                '1' => '女',
                '2' => '未知',
            ];
            $sex = $genderMap[$post['sex']] ?? '男';
            $where = [
                'dept_id'=>$post['dept_id']
            ];
            $deptData = $deptBus->getNormalDept($where,'dept_name,leader');
            $sheet->setCellValue('A' . $row, $post['user_id']);
            $sheet->setCellValue('B' . $row, $post['user_name']);
            $sheet->setCellValue('C' . $row, $post['nick_name']);
            $sheet->setCellValue('D' . $row, $post['email']);
            $sheet->setCellValue('E' . $row, $post['phonenumber']);
            $sheet->setCellValue('F' . $row, $sex);
            $sheet->setCellValue('G' . $row, $post['status']);
            $sheet->setCellValue('H' . $row, $post['login_ip']);
            $sheet->setCellValue('I' . $row, $post['login_date']);
            $sheet->setCellValue('J' . $row, $deptData[0]['dept_name']??'');
            $sheet->setCellValue('K' . $row, $deptData[0]['leader']??'');
            $row++;
        }
        $row = $row-1;
        $SpreadsheetObj = new \app\common\lib\Spreadsheet();
        $sheet->getStyle('A1')->applyFromArray($SpreadsheetObj->fontArray('FF000000',18));
        $sheet->getStyle('A2:K2')->applyFromArray($SpreadsheetObj->fillArray("808080"));
        $sheet->getStyle('A2:K2')->applyFromArray($SpreadsheetObj->fontArray("FFFFFFFF"));
        $sheet->getStyle('A1' . ':K' . $row)->applyFromArray($SpreadsheetObj->styleBorderArray());
        $sheet->getStyle('A1' . ':K' . $row)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
        // 创建Writer对象，并保存为xlsx文件
        $writer = new Xlsx($spreadsheet);
        // 设置响应头
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="post.xlsx"');
        header('Cache-Control: max-age=0');
        // 导出
        $writer->save('php://output');
        exit;
    }

    //分配角色列表
    public function userAuthRole(){
        $userId = $this->request->param("userId", "", "trim");
        if (empty($userId)) {
            return show(config("status.error"), "用户ID不能为空");
        }

        try {
            // 获取用户信息
            $userData = (new SysUserBus())->getUserById($userId);
            if (!$userData) {
                return show(config("status.error"), "用户不存在");
            }
            // 获取用户角色ID
            $rolesIdArr = (new SysUserRole())->getRoleIds($userId);
            // 获取所有非管理员角色的基本信息
            $allRoles = (new SysRoleBus())->getNormalRoleNotPage([
                ['del_flag', '=', 0],
                ['role_key', '<>', 'admin'],
            ]);
            // 处理角色数据，标记用户已分配的角色
            $userRoles = [];
            foreach ($allRoles as $role) {
                $role['flag'] = in_array($role['role_id'], $rolesIdArr);
                $userRoles[] = $role;
            }
            // 获取用户已分配角色的详细信息（如果需要）
            /*$userDetailedRoles = (new SysRoleBus())->getNormalRoleNotPage([
                ['role_id', 'in', $rolesIdArr],
            ]);*/
            // 组装返回数据
            $data = [
                'roles' => $userRoles,
                'user' => $userData,
            ];
            $data = (new toCamelCase())->toCamelCaseArray($data);
            return show(config("status.success"), "分配角色列表", $data);
        }catch(\Exception $e){
            return show(config("status.error"), $e->getMessage());
        }
    }

    //分配用户角色
    public function authRole(){
        $userId = $this->request->param("userId", "", "trim");
        $roleIds = $this->request->param("roleIds", "", "trim");
        if (empty($userId)) {
            return show(config("status.error"), "用户ID不能为空");
        }
        try {
            Db::instance();
            (new SysUserRole())->deleteAllUserRole($userId);
            if($roleIds){
                $roleIds = explode(',',$roleIds);
                (new SysUserRole())->insertAllUserRole($userId,$roleIds);
            }
            Db::commit();
            return show(config("status.success"),"操作成功");
        }catch (\Exception $e){
            Db::rollback();
            return show(config('status.error'),$e->getMessage());
        }
    }

    //个人中心
    public function userProfile(){
        try {
            $userData = (new SysUserBus())->getUserById($this->userId);
            $deptBus = new SysDeptBus();
            $deptData = $deptBus->getFindNormalDept(['dept_id' => $userData['dept_id']]);
            $userData['dept'] = $deptData;
            $postIds = (new SysUserPost())->getPostIds($this->userId);
            $map = [
                ['post_id','in',$postIds]
            ];
            $postGroup = (new SysPostBus())->getNormalPostFiled($map);
            $roleIds = (new SysUserRole())->getRoleIds($this->userId);
            $where = [
                ['role_id','in',$roleIds]
            ];
            $userData['roles'] = (new SysRoleBus())->getNormalRoleNotPage($where);
            $roleGroup = (new SysRoleBus())->getNormalRoleFiled($where);
            $data = [
                'data'=>$userData,
                'postGroup'=>implode(',',$postGroup),
                'roleGroup'=>implode(',',$roleGroup),
            ];
            $data = (new toCamelCase())->toCamelCaseArray($data);
        }catch (\Exception $e){
            $data = [];
        }
        return show(config("status.success"),"个人中心",$data);
    }

    //修改用户中心
    public function userProfileEdit(){
        //参数校验
        $allParams = request()->param();
        $data = (new toCamelCase())->toCamelCaseArray($allParams,'1',2);
        try {
            $result = (new SysUserBus())->updateById($this->userId,$data,false);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"修改成功",$result);
    }

    //个人中心修改密码
    public function profileUpdatePwd(){
        if (!$this->request->isPut()) {
            return show(config("status.error"), "请求方式错误");
        }
        // 参数校验
        $params = request()->param();
        // 验证旧密码
        $user = (new SysUserBus())->getUserById($this->userId);
        if((string)(md5(config("redis.password_salt").$params['oldPassword']) !== (string)$user['password'])) {
            return show(config('status.error'),'旧密码错误');
        }
        $data = [
            'password' => $params['newPassword'] ? md5(config("redis.password_salt").$params['newPassword']) : '',
        ];
        try {
            $result = (new SysUserBus())->updateById($this->userId,$data,false);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"修改成功",$result);
    }

    // 上传头像
    public function uploadAvatar()
    {
        // 检查是否有文件上传
        $file = \think\facade\Request::file('avatarfile');
        if (!$file) {
            return show(config("status.error"), "请上传文件");
        }
        // 文件保存路径配置
        $saveName = \think\facade\Filesystem::disk('public')->putFile('avatars', $file);
        // 获取访问URL
        $accessUrl = \think\facade\Filesystem::disk('public')->url($saveName);
        // 返回上传信息
        $data = [
            'avatar' => $accessUrl,
        ];
        try {
            (new SysUserBus())->updateById($this->userId,$data,false);
        }catch (\Exception $e){
            return show(config('status.error'),$e->getMessage());
        }
        return show(config("status.success"),"修改成功",['imgUrl'=>$accessUrl]);
    }
}
